import os
import sys

# 设置embeddings利用的gpu
os.environ['CUDA_VISIBLE_DEVICES'] = "1" 
# add project lib to python env
ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(ROOT_PATH)
sys.path[0] = ROOT_PATH
os.environ["ROOT_PATH"] = ROOT_PATH
# read .env
from dotenv import load_dotenv

ENV_PATH = os.path.join(ROOT_PATH, ".env")
load_dotenv(dotenv_path=ENV_PATH, verbose=True)

from utils import INFO,DEBUG

import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from app.router import RegisterRouterList
from app.middleware import loginCheck as tokenCheck
from app.config import SERVER_IP,SERVER_PORT,DEFAULT_STATIC_PATH

from app.utils import Response
from fastapi.responses import JSONResponse
from app.constant import ERRORCODE

from utils import ERROR

## 实例化
app = FastAPI()

## 配置跨域
# 配置允许域名
origins = [
    "http://127.0.0.1:8080",
]
# 配置允许域名列表、允许方法、请求头、cookie等
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    # 不需要cookie
    allow_credentials=False,
    allow_methods=["*"],
    allow_headers=["*"],
)
staticPath = DEFAULT_STATIC_PATH
INFO("static path: " + staticPath)
## 配置静态资源路径
app.mount("/static", StaticFiles(directory = staticPath), name="static")    

@app.middleware("http")
async def loginCheck(request: Request, call_next):
    # 浏览器预检，告诉浏览器有这个资源
    if request.method == "OPTIONS":
        try:
            response = await call_next(request)
            return response
        except Exception as e:
            raise  e
            ERROR(e)
            return JSONResponse(Response(ERRORCODE.RESPONSE_SERVER_ERROR), 200)
        

    # 读取路径
    path = request.scope["path"]
    # print(request.scope)
    DEBUG(path)
    # 静态地址过滤,读取图片的
    drop = True
    try:
        if path.index('/static') == 0:
            drop = False
    except Exception as e:
        pass
    
    
    if not drop:
        try:
            response = await call_next(request)
            return response
        except Exception as e:
            raise  e
            ERROR(e)
            return JSONResponse(Response(ERRORCODE.RESPONSE_SERVER_ERROR), 200)
    
    drop = True
    try:
        if path.index('/download') == 0:
            drop = False
    except Exception as e:
        pass
    
    
    if not drop:
        try:
            response = await call_next(request)
            return response
        except Exception as e:
            raise  e
            ERROR(e)
            return JSONResponse(Response(ERRORCODE.RESPONSE_SERVER_ERROR), 200)
    
    
    # 账户登陆地址和注册地址过滤
    # print(request.headers.keys())
    print(request.headers)
    # 如果路径不是登陆或者注册，需要检验token
    if path != "/login" and path != "/register" :
        if 'token' not in request.headers.keys():
            return JSONResponse(Response(ERRORCODE.RESPONSE_REDIRECT_LOGIN), headers={"Access-Control-Allow-Origin": origins[0]})
        token = request.headers["token"]
        
        if token != None:
            if tokenCheck(token, request):     
                print(request.scope.keys())
                try:
                    response = await call_next(request)
                    if "new-token" in request.scope.keys():
                        response.headers["new-token"] = request.scope["new-token"]
                    return response
                except Exception as e:
                    raise  e
                    ERROR(e)
                    return JSONResponse(Response(ERRORCODE.RESPONSE_SERVER_ERROR), 200)
    # 登陆注册地址不校验token
    else:
        try:
            response = await call_next(request)
            return response
        except Exception as e:
            raise  e
            ERROR(e)
            return JSONResponse(Response(ERRORCODE.RESPONSE_SERVER_ERROR), 200)
    return JSONResponse(Response(ERRORCODE.RESPONSE_REDIRECT_LOGIN, headers={"Access-Control-Allow-Origin": origins[0], }))

## 浏览器预检
@app.options(".*")
async def preCheck():
    return {}


## 加载路由
for item in RegisterRouterList:
    app.include_router(item.router)

if __name__ == "__main__":
    uvicorn.run(app, host=SERVER_IP, port=SERVER_PORT)

